	<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Tetris</title>
</head>
<body>
	<div id="wrapper">
		<canvas id="canv">
			Here's the game.
		</canvas>
		<div id="side">
			<div class="label">Score:</div>
			<div id="score">0</div>
		</div>
	</div>

</body>
</html>
    	<style>#wrapper{
	margin: auto;
	width: 600px;
	height: 600px;
	background-color: #777;
}
#canv{
	background-color: #000;
}
#side{
	width: 180px;
	font-size: 3rem;
	color: #fff;
	text-align: left;
	float: right;
}</style>
	    		<script>/*************
 * = Init Canvas
 *************/
var c = document.getElementById( 'canv' );

c.width = "400";
c.height = "600";
var ctx = c.getContext( "2d" );

var pixel = 40;

/*************
 * = Tetris Piece
 *************/
var branches = [
	[[-1, 0], [-1, 1], [0, 1]],
	[[1, 0], [0, 1], [-1, 1]],
	[[-1, 0], [0, 1], [1, 1]],
	[[1, 0], [-1, 0], [0, 1]],
	[[1, 0], [2, 0], [-1, 0]],
	[[-1, 0], [1, 0], [1, -1]],
	[[-1, 0], [1, 0], [-1, -1]]
];
function piece(){
	this.pos = [Math.floor( board.col/2 ), 0];
	this.variant = Math.floor( Math.random()*branches.length );
	this.branch = branches[this.variant].slice();
}

piece.prototype.drop = function(){
	this.pos[1]++;
}

piece.prototype.getBranch = function( index ){
	return [this.pos[0]+this.branch[index][0],
			this.pos[1]+this.branch[index][1]];
}

piece.prototype.checkBound = function( step ){
	for( var i = 0; i < this.branch.length; i++ ){
		if( step <= 0 ){
			if( this.getBranch( i )[0]+step < 0 ){
				return true;
			}
		}
		if( step >= 0 ){
			if( this.getBranch( i )[0]+step > board.col-1 ){
				return true;
			}
		}
	}
	return false;
}

piece.prototype.rotate = function( back ){
	back = back || false;
	if( this.variant == 0 )return;
	if( this.variant == 1 || this.variant == 2 ){
		if( this.turn = !this.turn ){
			for( var i = 0; i < this.branch.length; i++ ){
				this.branch[i] = [this.branch[i][1], -this.branch[i][0]];
			}
		}else{
			for( var i = 0; i < this.branch.length; i++ ){
				this.branch[i] = [-this.branch[i][1], this.branch[i][0]];
			}
		}
		return;
	}
	for( var i = 0; i < this.branch.length; i++ ){
		this.branch[i] = back? [-this.branch[i][1], this.branch[i][0]]:
			[this.branch[i][1], -this.branch[i][0]];
	}
}

/*************
 * = Aid function
 *************/
function drawPixel( i, j, color ){
	color = color || "#eee";
	ctx.strokeStyle = "#000";
	ctx.lineWidth = 4;
	ctx.fillStyle = color;
	
	ctx.fillRect( i * pixel, j * pixel,
		pixel, pixel );
	ctx.strokeRect( i * pixel, j * pixel,
		pixel, pixel );
}

/*************
 * = Main Board
 *************/
board = {
	row: 15,
	col: 10,
	initv: 0,
	piece: undefined,

	newpiece: function(){
		this.piece = new piece();
	},

	init: function(){
		this.field = [this.col];
		for( var i = 0; i<this.col; i++ ){
			this.field[i] = [this.row];
			for( var j = 0; j < this.row; j++ ){
				this.field[i][j] = this.initv;
			}
		}
		this.newpiece();
	},

	drawPiece: function(){
		if( !!this.piece ){
			drawPixel( this.piece.pos[0], this.piece.pos[1], "#7878e3" );
			var b;
			for( var i = 0; i < this.piece.branch.length; i++ ){
				b = this.piece.getBranch( i );
				drawPixel( b[0], b[1], "#7878e3" );
			}
		}
	},

	drawBoard: function(){
		for( var i = 0; i < board.field.length; i++ ){
			for( var j = 0; j < board.field[0].length; j++ ){
				if( board.field[i][j] > 0 ){
					drawPixel( i, j );
				}
			}
		}
	},

	checkOccupied: function( dx, dy ){
		var x, y, f;
		f = this.piece.pos;
		x = f[0] + dx;
		y = f[1] + dy;
		if( this.field[x][y] > 0 || y >= this.row ){
			return true;
		}
		for( var i = 0; i < this.piece.branch.length; i++ ){
			f = this.piece.getBranch( i );
			if( this.field[f[0]+dx][f[1]+dy] > 0 || f[1]+dy >= this.row ){
				return true;
			}
		}
		return false;
	},

	digest: function(){
		var b = this.piece.pos;
		this.field[b[0]][b[1]] = 1;
		for( var i = 0; i < this.piece.branch.length; i++ ){
			b = this.piece.getBranch( i );
			this.field[b[0]][b[1]] = 1;
		}
		this.newpiece();
		if(this.checkOccupied(0,0)){
			//alert("Game Over!");
			window.clearInterval(compute);
		}
	},

	checkFull: function(){
		var linefull;
		for( var i = 0; i < this.row; i++ ){
			linefull = true;
			for( var j = 0; j < this.col; j++ ){
				if( this.field[j][i] == 0 ){
					linefull = false;
				}
			}
			if( linefull ){
				return i;
			}
		}
		return -1;
	}

};

board.init();

/*************
 * = Player Control
 *************/
window.addEventListener( "keydown", function( e ){
	switch( e.keyCode ){
		case 37:
			if( !board.piece.checkBound( -1 )
				&& !board.checkOccupied( -1, 0 ) )
				board.piece.pos[0]--;
			break;
		case 39:
			if( !board.piece.checkBound( 1 )
				&& !board.checkOccupied( 1, 0 ) )
				board.piece.pos[0]++;
			break;
		case 38:
			board.piece.rotate();
			if( board.piece.checkBound( 0 ) || board.piece.checkBound( 0 ) || board.checkOccupied( 0, 0 ) ){
				board.piece.rotate( true );
			}
			break;
		case 40:
			while( !board.checkOccupied( 0, 1 ) ){
				board.piece.drop();
			}
			break;
		default:
			// console.log( e.keyCode );
			break;
	}
} );

/*************
 * = Canvas functions
 *************/

function clear(){
	ctx.fillStyle = "#000";
	ctx.fillRect( 0, 0, c.width, c.height );
}

function draw(){
	clear();
	board.drawBoard();
	board.drawPiece();
}

var score = document.getElementById( "score" );
var rscore = 0;
var multiplier = 0;
var line = -1;
var row;
function update(){
	if( !!board.piece ){
		if( board.checkOccupied( 0, 1 ) ){
			board.digest();
			return;
		}
		board.piece.drop()
	}
	line = -1;
	multiplier = 0;
	while( ( line = board.checkFull() ) >= 0 ){
		for( var i = 0; i < board.col; i++ ){
			row = board.field[i];
			row.splice( line, 1 );
			row.unshift( 0 );
		}
		multiplier = multiplier * 2 + 1;
	}
	rscore += 100 * multiplier;
	score.innerHTML = rscore;
}

/*************
 * = Cycle Control
 *************/
var render = setInterval( "draw()", 1000/60 );
var compute = setInterval( "update()", 400 );</script>
	
<!-- Generated by RunJS (Mon Aug 04 14:24:25 CST 2014) 1ms -->